package com.zhufeng.gateway.db.filter;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @ClassName: AuthSignatureFilter
 * @Description 鉴权
 * @author 月夜烛峰
 * @date 2022/9/20 19:09
 */
@Slf4j
@Component
public class AuthSignatureGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthSignatureGatewayFilterFactory.Config> {

    public AuthSignatureGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(AuthSignatureGatewayFilterFactory.Config config) {
        return (exchange, chain) -> {

            log.info("权限校验...." + config.getSignInfo());
            ServerHttpRequest serverHttpRequest = exchange.getRequest();
            ServerHttpResponse serverHttpResponse = exchange.getResponse();
            String methodName = serverHttpRequest.getMethodValue();
            if ("GET".equals(methodName)) {
                String resp = "请求被拦截!";
                JSONObject signJson = map2json(serverHttpRequest);
                log.info("GET——参数:" + signJson);


                DataBuffer bodyDataBuffer = serverHttpResponse.bufferFactory().wrap(resp.getBytes());
                serverHttpResponse.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
                return serverHttpResponse.writeWith(Mono.just(bodyDataBuffer));
            } else if ("POST".equals(methodName)) {
                String bodyStr = resolveBodyFromRequest(exchange.getRequest());
                log.info("POST——bodyStr："+bodyStr);
            }


            return chain.filter(exchange);
        };
    }

    private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) {
        //获取请求报文体
        Flux<DataBuffer> body = serverHttpRequest.getBody();

        AtomicReference<String> bodyRef = new AtomicReference<>();
        body.subscribe(buffer -> {
            CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
            DataBufferUtils.release(buffer);
            bodyRef.set(charBuffer.toString());
        });
        log.info("获取请求体:"+bodyRef.get());
        //获取request body
        return bodyRef.get();
    }

    public JSONObject map2json(ServerHttpRequest request) {
        MultiValueMap<String, String> muMap = request.getQueryParams();

        JSONObject reqJson = new JSONObject();
        for (Map.Entry<String, List<String>> entry : muMap.entrySet()) {

            reqJson.put(entry.getKey(), entry.getValue().get(0));

        }
        return reqJson;
    }

    public static class Config {

        private JSONObject signInfo;

        public JSONObject getSignInfo() {
            return signInfo;
        }

        public Config setSignInfo(JSONObject signInfo) {
            this.signInfo = signInfo;
            return this;
        }

    }
}